﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HurSimLib
{
    /// <summary>
    /// The class that represents objects or individuals being processed in the system
    /// </summary>
    public class HurObject
    {
        /// <summary>
        /// The time at which the object first appears in the system
        /// </summary>
        private DateTime m_creationtime;
        /// <summary>
        /// The current time for the object.
        /// This will be updated everytime the object exits a process.
        /// </summary>
        private DateTime m_currenttime;
        /// <summary>
        /// The total time the object has spent in waiting
        /// </summary>
        private DateTime totalWaitingTime;

        public DateTime TotalWaitingTime
        {
            get { return totalWaitingTime; }
            set { totalWaitingTime = value; }
        }
        /// <summary>
        /// Total time in which the object has received service (not necessarily by the same process)
        /// </summary>
        private DateTime totalServiceTime;

        public DateTime TotalServiceTime
        {
            get { return totalServiceTime; }
            set { totalServiceTime = value; }
        }

        /// <summary>
        /// The constructor requires a creation time (which will be set by an object generator)
        /// </summary>
        /// <param name="creationtime"></param>
        public HurObject(DateTime creationtime)
        {
            m_currenttime = m_creationtime = creationtime;
            totalServiceTime = default(DateTime);
            totalWaitingTime = default(DateTime);
        }

        public DateTime CurrentTime
        {
            get { return m_currenttime; }
        }

        /// <summary>
        /// This function may be called by the process to let the object know about
        /// the start time of the service and decide whether to balk or submit.
        /// </summary>
        /// <param name="process"></param>
        /// <param name="servicestarttime"></param>
        /// <returns></returns>
        public bool EnterProcess(HurProcess process, DateTime servicestarttime)
        {
            // We currently assume that every object will submit to the process.
            // However, we could write code to calculate the expected waiting time
            // and let the object to run out of the system.
            bool bAcceptEntry = true;

            // If accepting entry, the object should record the expected waiting time.
            // This record could also be done in a database.
            if (bAcceptEntry)
            {
                totalWaitingTime += (servicestarttime - m_currenttime);
                m_currenttime = servicestarttime;
            }

            return bAcceptEntry;
        }

        /// <summary>
        /// This function may be called by the process to let the object know
        /// when the service eneded.
        /// </summary>
        /// <param name="process"></param>
        /// <param name="serviceendtime"></param>
        public void ExitProcess(HurProcess process, DateTime serviceendtime)
        {
            totalServiceTime += (serviceendtime - m_currenttime);
            m_currenttime = serviceendtime;
        }
    }
}
